use std::{collections::VecDeque, ops::Range};

use rand::{rngs::ThreadRng, thread_rng, Rng};

pub struct Random {
    rng: ThreadRng,
    history: VecDeque<usize>,
}

impl Random {
    pub fn new(history_size: usize) -> Self {
        Self {
            rng: thread_rng(),
            history: VecDeque::with_capacity(history_size),
        }
    }

    pub fn gen_range(&mut self, range: Range<usize>) -> usize {
        if self.history.len() < self.history.capacity() {
            let num = self.rng.gen_range(range);
            self.history.push_back(num);
            num
        } else {
            let num = loop {
                let num = self.rng.gen_range(range.clone());
                if num != *self.history.front().unwrap() {
                    self.history.pop_front();
                    break num;
                }
            };
            self.history.push_back(num);
            num
        }
    }
}
